/*
 * FileIndexer.java
 *
 * Created on March 22, 2008, 8:50 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.afaker.searth.core.index.impl;

import com.afaker.searth.core.index.DefaultIndexer;
import com.afaker.searth.core.index.handler.FileHandler;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.PriorityQueue;
import java.util.Queue;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;

/**
 *
 * @author bruce
 */
public class FileIndexer extends DefaultIndexer{
    private static Logger log =
            Logger.getLogger(FileIndexer.class);
    private String directoryPath = "";
    private boolean isCancelIndex;
    private boolean done;
    private boolean indexing;
    private boolean includePlainText;
    protected static final int MAX_FILE_SIZE = 24;
    private FileFilter filter;
    private FileHandler fileHandler;
    /**
     * Creates a new instance of FileIndexer
     */
    public FileIndexer() {
        fileHandler = new FileHandler();
    }
    
    public String getDirectoryPath() {
        return directoryPath;
    }
    
    public void setDirectoryPath(String directoryPath) {
        this.directoryPath = directoryPath;
    }
    
    public void setIncludePlainText(boolean includePlainText) {
        this.includePlainText = includePlainText;        
    }
    
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        FileIndexer index = new FileIndexer();
        index.setDirectoryPath("/home/bruce/index/");
        try {
            index.index();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    public boolean isDone(){
        return done;
    }
    public boolean isIndexing(){
        return indexing;
    }
    
    public void cancelIndex(){
        isCancelIndex = true;
    }
    /**
     * Append some kind of file formats you don't wanna to index.
     * @param format The file format like php,txt,doc,etc.
     */
    public void addStopFormat(int format){
        fileHandler.addStopformat(format);
    }    

    protected void indexDocuments() {
        fileHandler.setIndexPlainText(includePlainText);
        setDocumentHandler(fileHandler);
        File dir = new File(directoryPath);
        if(!dir.exists()) {
            log.info(" File " + dir.getAbsolutePath() + " does not exists.");
            return ;
        }
        isCancelIndex = false;
        indexing = true;
        done = false;
        add2Documents(dir);
        done = true;
        fileHandler.clearStopFormat();
    }
    /**
     * Recursively lookup directories to add files to Lucene's Documents.
     * @param file 
     */
    private void add2Documents(File file){
        Queue<File> q = new PriorityQueue<File>();
        q.add(file);
        while(q.size() > 0){
            if(isCancelIndex)
                return ;
            File current = q.poll();
            if(current.isFile()){
                double length = current.length()/1024.0/1024.0;
                if(length >= MAX_FILE_SIZE) {
                    log.warn("File " + current.getAbsolutePath() + " size is greater than " + MAX_FILE_SIZE + "M");
                    continue ;
                }
                if(!current.canRead() || !current.exists()) {
                    log.info(current.getAbsolutePath() + " does not exist or is not readable.");
                    continue ;
                }
                log.info("Indexing:" + current.getAbsolutePath());
                Document doc = docHandler.getDocument(current);
                if(doc == null)
                    continue ;
                System.gc();
                documents.add(doc);
                System.gc();
            } else if(current.isDirectory()){
                File[]  files = current.listFiles(filter);
                if(files == null)
                    continue;
                for (int i = 0; i < files.length; i++) {
                    q.add(files[i]);
                }
            }
        }
    }
}
